#include "networkcommunicator.h"
#include <QDebug>
#include <QtScript/QScriptValueIterator>
#include <QRegExp>
#include <QtGui>

NetworkCommunicator* NetworkCommunicator::inst = 0;

NetworkCommunicator::NetworkCommunicator(QObject *parent) : QNetworkAccessManager(parent)
{

}

NetworkCommunicator* NetworkCommunicator::instance()
{
    if(inst == NULL)
        inst = new NetworkCommunicator;
    return inst;
}

void NetworkCommunicator::findStreamUrl(QString id)
{
    qDebug() << "Launching request for: www.youtube.com/get_video_info?video_id=" +id;
    QNetworkRequest request(QUrl("http://www.youtube.com/get_video_info?video_id=" + id));
    QNetworkReply* reply = get(request);
    connect(reply, SIGNAL(finished()), this, SLOT(gotVideoInfo()));
}

void NetworkCommunicator::gotVideoInfo()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
    qDebug("Retrieved video info! Bytes received:");
    qDebug(QString::number(reply->bytesAvailable()).toStdString().c_str());

    QString data = QString::fromUtf8(reply->readAll());

    //data = data.left(1000);

    // GET TOKEN
    QRegExp regex = QRegExp("^.*&token=([^&]+).*$");
    bool foundToken = regex.exactMatch(data);
    qDebug(QString("Found token: %1").arg(foundToken).toAscii());
    if(foundToken)
    {
        QString token = regex.cap(1);
        while(token.contains("%"))
            token = QByteArray::fromPercentEncoding(token.toAscii());
        qDebug(token.toAscii());
    }
    else
    {
        qDebug("failed to find token");
    }

    // GET STREAM URL
    QRegExp r("^.*url%3D([^&]+).*$");
    bool foundStreamUrl = r.exactMatch(data);
    if(foundStreamUrl)
    {
        QString streamUrl( r.cap(1));

        streamUrl = QByteArray::fromPercentEncoding(streamUrl.toAscii());

        QStringList urls = streamUrl.split(",", QString::SkipEmptyParts);
        for(QList<QString>::Iterator itr = urls.begin(); itr != urls.end(); itr++)
        {
            QString url = (*itr);
            qDebug() << url.left(100);
            while(url.contains("%"))
                url = QByteArray::fromPercentEncoding(url.toAscii());
            if(url.contains("itag=18")){
                url = url.left(url.indexOf("&quality="));
                emit newStreamUrlFound(QUrl(url));
            }
        }






        //qDebug(streamUrl.toAscii());


    }
    else
    {
        qDebug("failed to find stream");
    }



}

void NetworkCommunicator::search(QString tag)
{
    tag = tag.trimmed();
    tag.replace(' ', '/');
    QNetworkRequest request(QUrl("https://gdata.youtube.com/feeds/api/videos/-/" + tag + "/lyrics/-VEVO?category=Music&v=2&alt=json&format=5"));
    QNetworkReply* reply = get(request);
    connect(reply, SIGNAL(finished()), this, SLOT(videoSearchCompleted()));
}

void NetworkCommunicator::videoSearchCompleted()
{
    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());

    QString data = QString::fromUtf8(reply->readAll());
    qDebug() << data.left(100);

    QScriptEngine engine;
    QScriptValue result = engine.evaluate("(" + data + ")");

    QList<VideoInfo> vidlist;
    if(result.property("feed").property("entry").isArray())
    {
        QScriptValueIterator entry(result.property("feed").property("entry"));
        while(entry.hasNext())
        {
            entry.next();
            bool allowRemoteAcces = true;
            QScriptValueIterator action(entry.value().property("yt$accessControl"));
            while(action.hasNext())
            {
                action.next();
                qDebug() << action.value().property("action").toString();
                qDebug() << action.value().property("permission").toString();
                if(action.value().property("action").toString() == "autoPlay" && action.value().property("permission").toString() == "denied")
                {
                    qDebug() << action.value().property("action").toString().toUpper();
                    qDebug() << action.value().property("permission").toString().toUpper();
                    allowRemoteAcces = false;
                }
            }

            if(allowRemoteAcces)
            {
                VideoInfo vid;

                vid.title = entry.value().property("title").property("$t").toString();
                vid.id = entry.value().property("media$group").property("yt$videoid").property("$t").toString();
                vid.duration = entry.value().property("media$group").property("yt$duration").property("seconds").toInteger();
                vidlist.append(vid);
            }
            else
                qDebug("Filtered this bitch out");
        }
    }

    emit newSearchDone(vidlist);
}
